using System;
using System.Collections.Generic;
using System.Text;

namespace SharpMud.Net.Telnet.ANSI
{
    /// <summary>
    /// Used to link abritrary enum-based definitions of color to their ANSI equivalents
    /// </summary>
    [AttributeUsage(AttributeTargets.Field)]
    internal class AnsiRepresentationAttribute : System.Attribute
    {
        private BasicColor _BasicColor;
        private ColorScope _ColorScope;
        private bool _UseBright;

        private string _Sequence;

        public AnsiRepresentationAttribute(BasicColor basicAnsiColor, ColorScope colorScope)
            : this(basicAnsiColor, colorScope, false)
        { }
        public AnsiRepresentationAttribute(BasicColor basicAnsiColor, ColorScope colorScope, bool useBright)
        {
            if (colorScope == ColorScope.Background && useBright == true)
            {
                throw new ArgumentException("You cannot combine the 'bright' attribute with a background color.");
            }
            if(!System.Enum.IsDefined(typeof(ColorScope),colorScope))
                throw new ArgumentException("Argument value undefined.","colorScope");
            if (!System.Enum.IsDefined(typeof(BasicColor), basicAnsiColor))
                throw new ArgumentException("Argument value undefined.", "basicAnsiColor");

            _BasicColor = basicAnsiColor;
            _ColorScope = colorScope;
            _UseBright = useBright;

            _Sequence = ANSI.Utility.SetTextColor(_BasicColor,_ColorScope,_UseBright);
        }

        /// <summary>
        /// The basic ANSI color
        /// </summary>
        public BasicColor BasicColor
        {
            get
            {
                return _BasicColor;
            }
        }

        /// <summary>
        /// Whether or not the color is foreground or background
        /// </summary>
        public ColorScope ColorScope
        {
            get
            {
                return _ColorScope;
            }
        }

        /// <summary>
        /// Whether or not the ANSI 'bold'/'bright' code should be used to produce the color
        /// </summary>
        public bool UseBright
        {
            get
            {
                return _UseBright;
            }
        }

        /// <summary>
        /// The ANSI sequence that represents this color
        /// </summary>
        public string Sequence
        {
            get
            {
                return _Sequence;
            }
        }

        /// <summary>
        /// Find the instance of AnsiRepresentationAttribute for the specific value in the specific enum
        /// </summary>
        public static AnsiRepresentationAttribute FindForValue<T>(T value)
        {
            if (typeof(T).IsEnum == false)
                throw new ArgumentException("Type <T> must be an Enum!");

            foreach (System.Reflection.FieldInfo fi in (typeof(T)).GetFields())
            {
                if (fi.Name.ToLower().Trim() == value.ToString().ToLower().Trim())
                {
                    foreach (AnsiRepresentationAttribute ara in fi.GetCustomAttributes(typeof(AnsiRepresentationAttribute), true))
                    {
                        return ara;
                    }
                }
            }

            return null;
        }
    }
}
